C# winform PictureBox显示opencv Mat图片 您所在的位置:网站首页 winform 显示上千张图片 C# winform PictureBox显示opencv Mat图片

C# winform PictureBox显示opencv Mat图片

2024-07-15 17:07| 来源: 网络整理| 查看: 265

在winform设计器托一个PictureBox、一个按钮,界面如下: 在这里插入图片描述

代码

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using OpenCvSharp; //引入opencv using OpenCvSharp.Extensions; //Mat转换时需要该模块 namespace PictureBoxShowMat { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { OpenFileDialog dialog = new OpenFileDialog(); dialog.Multiselect = false; //是否可以选择多个文件 dialog.Title = "请选择文件夹"; dialog.Filter = "所有文件(*.*)|*.*"; dialog.RestoreDirectory = true; string imgName = ""; if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { imgName = dialog.FileName; //读取本地的图片 Mat srcImg = new Mat(imgName, ImreadModes.Color); //把Mat格式的图片转换成Bitmap Bitmap bitmap = BitmapConverter.ToBitmap(srcImg); //显示图片 pictureBox1.Image = bitmap; } } } }

运行结果 在这里插入图片描述

Mat转Bitmap需要调用OPenCVSharp拓展模块OpenCvSharp.Extensions, 调用该模块BitmapConverter类的一些方法即可完成相应的转换,该类声明如下: 在这里插入图片描述 BitmapConverter类定义了一些静态方法,可以把Mat转为Bitmap, 也可以把Bitmap转为Mat. 来看看转Bitmap的源码,在OpenCVSharp源码中查找BitmapConverter类的实现,ToBitmap的实现如下:

/// /// Converts Mat to System.Drawing.Bitmap /// /// Mat /// public static Bitmap ToBitmap(this Mat src) { if (src == null) { throw new ArgumentNullException(nameof(src)); } PixelFormat pf; switch (src.Channels()) { case 1: pf = PixelFormat.Format8bppIndexed; break; case 3: pf = PixelFormat.Format24bppRgb; break; case 4: pf = PixelFormat.Format32bppArgb; break; default: throw new ArgumentException("Number of channels must be 1, 3 or 4.", nameof(src)); } return ToBitmap(src, pf); }

根据图片的通道数,最终会调用下面这个方法转换

public static unsafe void ToBitmap(this Mat src, Bitmap dst) { if (src == null) throw new ArgumentNullException(nameof(src)); if (dst == null) throw new ArgumentNullException(nameof(dst)); if (src.IsDisposed) throw new ArgumentException("The image is disposed.", nameof(src)); if (src.Depth() != MatType.CV_8U) throw new ArgumentException("Depth of the image must be CV_8U"); //if (src.IsSubmatrix()) // throw new ArgumentException("Submatrix is not supported"); if (src.Width != dst.Width || src.Height != dst.Height) throw new ArgumentException(""); PixelFormat pf = dst.PixelFormat; // 1プレーン用の場合、グレースケールのパレット情報を生成する if (pf == PixelFormat.Format8bppIndexed) { ColorPalette plt = dst.Palette; for (int x = 0; x bd = dst.LockBits(rect, ImageLockMode.WriteOnly, pf); IntPtr srcData = src.Data; byte* pSrc = (byte*)(srcData.ToPointer()); byte* pDst = (byte*)(bd.Scan0.ToPointer()); int ch = src.Channels(); int srcStep = (int)src.Step(); int dstStep = ((src.Width * ch) + 3) / 4 * 4; // 4の倍数に揃える int stride = bd.Stride; switch (pf) { case PixelFormat.Format1bppIndexed: { if (submat) throw new NotImplementedException("submatrix not supported"); // BitmapDataは4byte幅だが、IplImageは1byte幅 // 手作業で移し替える //int offset = stride - (w / 8); int x = 0; byte b = 0; for (int y = 0; y if (x var mask = (byte)(0x80 >> i); if (x for (int y = 0; y if (bd != null) dst.UnlockBits(bd); } } #endregion }

在转换的时候,会进行加锁处理,保证不会跳出当前的处理线程。

bd = dst.LockBits(rect, ImageLockMode.WriteOnly, pf); //像素转换 dst.UnlockBits(bd);


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有